//
//  Vector3.h
//  GSEngine
//
//  Created by Гукун Александр on 2/4/14.
//  Copyright (c) 2014 SNK. All rights reserved.
//

#ifndef __GSEngine__Vector3__
#define __GSEngine__Vector3__

#include <iostream>
#include <math.h>

namespace GSEngine
{
    template <typename T>
    struct vec3
    {
        typedef vec3<T> vec3T;
        T x,y,z;
        
        vec3():x(0),y(0) {}
        vec3(T newX, T newY, T newZ):x(newX),y(newY),z(newZ) {}
        vec3(T oneValue):x(oneValue),y(oneValue),z(oneValue) {}
        vec3T& operator=(const vec3T newVec)
        {
            x = newVec.x;
            y = newVec.y;
            z = newVec.z;
            return *this;
        }
        vec3T& operator=(const T oneValue)
        {
            x = y = z = oneValue;
            return *this;
        }
        T length()
        {
            return sqrtf(x * x + y * y + z * z);
        }
        void normalize()
        {
            (*this)/=length();
        }
        void normalize(const T newLength)
        {
            (*this)/=length();
            (*this)*=newLength;
        }
        vec3T& operator*=(const T value)
        {
            x *= value;
            y *= value;
            z *= value;
            return (*this);
        }
        vec3T operator*(const T value)
        {
            return vec3T(x*value, y*value, z*value);
        }
        vec3T& operator/=(const T value)
        {
            x /= value;
            y /= value;
            z /= value;
            return (*this);
        }
        vec3T operator/(const T value)
        {
            return vec3T(x/value, y/value, z/value);
        }
        vec3T getNormal(vec3T p1, vec3T p2, vec3T p3)
        {
            float x1 = p1.x, x2 = p2.x, x3 = p3.x;
            float y1 = p1.y, y2 = p2.y, y3 = p3.y;
            float z1 = p1.z, z2 = p2.z, z3 = p3.z;
            vec3 result;
            result.x = (y2-y1)*(z3-z1)-(y3-y1)*(z2-z1);
            result.y = (x2-x1)*(z3-z1)-(x3-x1)*(z2-z1);
            result.z = (x2-x1)*(y3-y1)-(x3-x1)*(y2-y1);
            return result;
        }
    };
    
    typedef vec3<float> vec3f;
    typedef vec3<double> vec3d;
    typedef vec3<int> vec3i;
    typedef vec3<unsigned int> vec3ui;
    typedef vec3<unsigned short> vec3us;
    
}



#endif /* defined(__GSEngine__Vector3__) */
